#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../../Include/constant/env.h"
#include "../../Include/constant/knn_info.h"
#include "../../Include/manager/log_manager.h"
#include "../../Include/util/array_util.h"
#include "../../Include/domain/knn_dataset.h"

/**
 * 返回数据文件的路径
 * @return
 */
char *GetDataFilePathByEnvUSERDOMAIN() {
    Info("返回数据文件的路径");


    char *env = getenv(USERDOMAIN);
    if (strcmp(env, USERDOMAIN_AT_HOME) == 0) {
        Info("在家中运行程序");
        return KNN_DATA_FILE_AT_HOME;
    }
    if (strcmp(env, USERDOMAIN_AT_COMPANY) == 0) {
        Info("在公司中运行程序");
        return KNN_DATA_FILE_AT_COMPANY;
    }
}

/**
 * 归一化。公式：newValue = (oldValue - min) / (max - min)
 * @param dataArray
 * @return
 */
char **Normalize(double (*dataArray)[KNN_FILE_COLUMN_SIZE]) {
    Info("归一化");

    // 行列互换
    double (*reverseArray)[KNN_FILE_COLUMN_SIZE] = RowColumnInterchange(dataArray);

    // 归一化
    for (int i = 0; i < KNN_FILE_ROW_SIZE; ++i) {
        double max = reverseArray[i][0];
        double min = reverseArray[i][0];
        for (int j = 0; j < KNN_FILE_COLUMN_SIZE; j++) {
            if (reverseArray[i][j] > max) {
                max = reverseArray[i][j];
            }
            if (reverseArray[i][j] < min) {
                min = reverseArray[i][j];
            }
        }
        for (int k = 0; k < KNN_FILE_COLUMN_SIZE; ++k) {
            reverseArray[i][k] = (reverseArray[i][k] - min) / (max - min);
        }
    }

    // 行列互换
    dataArray = RowColumnInterchange(reverseArray);

    return dataArray;
}

/**
 * 返回训练数据集、训练数据集标签、测试数据集、测试数据集标签
 * @param fileContent
 * @param normalizedArray
 * @return
 */
struct KnnDataset DifferentiateTrainingDatasetAndTestingDataset(double (*allDatasetLabel)[KNN_FILE_COLUMN_SIZE],
                                                                 double (*normalizedArray)[KNN_FILE_COLUMN_SIZE]) {
    Info("返回训练数据集、训练数据集标签、测试数据集、测试数据集标签");

    // 计算训练数据集行数和测试数据集行数
    int trainingDatasetRowNumber = round(KNN_FILE_ROW_SIZE * TRAINING_DATASET_PERCENTAGE);
    int testingDatasetRowNumber = KNN_FILE_ROW_SIZE - trainingDatasetRowNumber;

    // 分配训练数据和测试数据、标签
    double trainingDataset[trainingDatasetRowNumber][KNN_FILE_COLUMN_SIZE];
    double testingDataset[testingDatasetRowNumber][KNN_FILE_COLUMN_SIZE];
    char *trainingDatasetLabel[KNN_FILE_ROW_SIZE];// = (char *)malloc(KNN_FILE_ROW_SIZE * KNN_FILE_COLUMN_SIZE * sizeof(char));
    char *testingDatasetLabel[KNN_FILE_ROW_SIZE];
    for (int i = 0; i < KNN_FILE_ROW_SIZE; ++i) {
        // 训练数据和测试数据
        for (int j = 0; j < KNN_FILE_COLUMN_SIZE; j++) {
            if (i < trainingDatasetRowNumber) {
                trainingDataset[i][j] = *(*(normalizedArray + i) + j);
            } else{
                testingDataset[i][j] = *(*(normalizedArray + i) + j);
            }
        }
        // 标签
        if (i < trainingDatasetRowNumber) {
            strcpy(trainingDatasetLabel[i], *(allDatasetLabel + i));
        } else{
            strcpy(testingDatasetLabel[i], *(allDatasetLabel + i));
        }
    }

    struct KnnDataset knnDataset = {trainingDataset, trainingDatasetLabel, testingDataset, testingDatasetLabel};
//    double (*a)[KNN_FILE_COLUMN_SIZE] = trainingDataset;
//    knnDataset->trainingDataset = a;
//    knnDataset->trainingDatasetLabel = trainingDatasetLabel;
//    knnDataset->testingDataset = &testingDataset;
//    knnDataset->testingDatasetLabel = testingDatasetLabel;
    return knnDataset;
}
